package com.jsz.peini.service.coupon;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import com.jsz.peini.bean.coupon.CouponGet;
import com.jsz.peini.bean.coupon.CouponHistory;
import com.jsz.peini.bean.coupon.CouponInfo;
import com.jsz.peini.bean.coupon.CouponUser;
import com.jsz.peini.bean.coupon.CouponUserExample;
import com.jsz.peini.bean.order.OrderInfo;
import com.jsz.peini.bean.order.ScoreHistory;
import com.jsz.peini.bean.user.UserAccount;
import com.jsz.peini.common.constants.Constants;
import com.jsz.peini.common.util.SmsSendUtil;
import com.jsz.peini.mapper.coupon.CouponGetMapper;
import com.jsz.peini.mapper.coupon.CouponHistoryMapper;
import com.jsz.peini.mapper.coupon.CouponInfoMapper;
import com.jsz.peini.mapper.coupon.CouponUserMapper;
import com.jsz.peini.mapper.order.OrderInfoMapper;
import com.jsz.peini.mapper.order.ScoreHistoryMapper;
import com.jsz.peini.mapper.user.UserAccountMapper;
import com.jsz.peini.mapper.user.UserSmsMapper;
import com.jsz.peini.redis.base.RedisConstants;
import com.jsz.peini.redis.base.RedisUtil;

@Service
public class CouponInfoService {
	private static final Logger logger = LoggerFactory.getLogger(CouponInfoService.class);
	@Resource
	private CouponInfoMapper couponInfoMapper;
	@Resource
	private CouponUserMapper couponUserMapper;
	@Resource
	private CouponHistoryMapper couponHistoryMapper;
	@Resource
	private UserSmsMapper userSmsMapper;
	@Resource
	private CouponGetMapper couponGetMapper;
	@Resource
	private UserAccountMapper userAccountMapper;
	@Resource
	private OrderInfoMapper orderInfoMapper;
	@Resource
	private ScoreHistoryMapper scoreHistoryMapper;
	
	public List<LinkedHashMap<String,Object>> getCouponInfoByUserId(CouponInfo couponInfo){
		List<LinkedHashMap<String,Object>> couponInfoByUserId=couponInfoMapper.getCouponInfoByUserId(couponInfo);
		return couponInfoByUserId;
	}
	
	public List<LinkedHashMap<String,Object>> getCouponInfoByAll(){
		List<LinkedHashMap<String,Object>> couponInfo=couponInfoMapper.getCouponInfoByAll();
		return couponInfo;
	}
	
	public List<CouponUser> getCouponUserByUserId(CouponInfo couponInfo){
		List<CouponUser> couponUser=couponInfoMapper.getCouponUserByUserId(couponInfo);
		return couponUser;
	}
	
	@Transactional(rollbackFor=Exception.class)
	public void setCouponUserByUserId(CouponInfo couponInfo){
		couponInfoMapper.insertCouponUserByUserId(couponInfo);
		couponInfoMapper.updateCouponInfoByOne(couponInfo.getId());
	}
	
	@Transactional(rollbackFor=Exception.class)
	public void setCouponUserByJF(CouponInfo couponInfo){
		couponInfoMapper.updateCouponInfoByOne(couponInfo.getId());
		couponInfoMapper.setCouponUserByJF(couponInfo);
		couponInfoMapper.setUserAccountByJF(couponInfo);
	}
	
	public int selectCouponByDate(int couponId){
		int result = couponInfoMapper.selectCouponByDate(couponId);
		return result;
	}

	@Transactional(rollbackFor=Exception.class)
	public void insertCouponUserByJF(CouponInfo couponInfo){
		couponInfoMapper.updateCouponInfoByOne(couponInfo.getId());
		couponInfoMapper.insertCouponUserByUserId(couponInfo);
		couponInfoMapper.setUserAccountByJF(couponInfo);
	}
	
	public int selectMaxTask(CouponGet couponGet){
		int result = couponInfoMapper.selectMaxTask(couponGet);
		return result;
	}
	
	public int selectIsMaxTask(CouponGet couponGet){
		int result = couponInfoMapper.selectIsMaxTask(couponGet);
		return result;
	}
	
	public CouponGet selectGetByType(CouponGet couponGet){
		CouponGet cMap = couponInfoMapper.selectGetByType(couponGet);
		return cMap;
	}
	
	public CouponInfo getCouponInfoNum(int id){
		CouponInfo couponInfoNum=couponInfoMapper.getCouponInfoNum(id);
		return couponInfoNum;
	}
	
	public int getSumTask(String userId){
		int result = couponInfoMapper.getSumTask(userId);
		return result;
	}

	public List<LinkedHashMap<String, Object>> getCouponInfoList_allUnGet_byScore() {
		return couponInfoMapper.getCouponInfoList_allUnGet_byScore();
	}
	
	@Transactional
	public LinkedHashMap<String, Object> rushBuyCouponResult(List<CouponInfo> couponList,String userId,Integer type,String paramId){
		LinkedHashMap<String, Object> infoMap = new LinkedHashMap<String, Object>();
		try {
			for (CouponInfo couponInfo : couponList) {
				String regCnt = RedisUtil.get(RedisConstants.COUPON_GET+couponInfo.getId());
				logger.info("--------------------regCnt:"+regCnt+"------------------------------------------------");
				if(StringUtils.isBlank(regCnt)){
					CouponUserExample cuExample = new CouponUserExample();
					cuExample.createCriteria().andCouponIdEqualTo(couponInfo.getId());
					int cnt = couponUserMapper.countByExample(cuExample);
					RedisUtil.set(RedisConstants.COUPON_GET+couponInfo.getId(), String.valueOf(cnt));
					regCnt = String.valueOf(cnt);
				}
				
				int recvCnt = Integer.parseInt(regCnt);
				if(recvCnt < couponInfo.getCouponNum()){
					Jedis redis = RedisUtil.getRedis();
					redis.watch(RedisConstants.COUPON_GET+couponInfo.getId());
					Transaction trsn = redis.multi();
					trsn.set(RedisConstants.COUPON_GET+couponInfo.getId(), String.valueOf(recvCnt));
					List<Object> objList = trsn.exec();
					if(objList != null && objList.size() > 0){
						//领取成功，将数据写入缓存
						RedisUtil.set(RedisConstants.COUPON_GET+couponInfo.getId(),String.valueOf(recvCnt+1));
						
						if(type == 1){//活动领取
							
						}else if(type == 10 || type == 2){						
							CouponUser couponUser = new CouponUser();
							couponUser.setGetTime(new Date());
							couponUser.setId(UUID.randomUUID().toString().replace("-", ""));
							couponUser.setCouponId(couponInfo.getId());
							couponUser.setCouponNum(1);
							couponUser.setGetType(type);
							couponUser.setUserId(userId);
							couponUserMapper.insert(couponUser);
							
							CouponHistory chis = new CouponHistory();
							chis.setHisId(UUID.randomUUID().toString().replace("-", ""));
							chis.setCreateTime(new Date());
							chis.setUserId(couponUser.getUserId());
							chis.setOpType(1);
							chis.setIsFinish(1);
							chis.setValNum(1l);
							chis.setHisType(type);
							chis.setParamId(couponUser.getParamId());
							chis.setIsDel(1);
							chis.setCouponId(couponUser.getCouponId());
							couponHistoryMapper.insertSelective(chis);
							
							couponInfo = couponInfoMapper.selectByPrimaryKey(couponInfo.getId());
							Long recvNum = (long)recvCnt+1;
							couponInfo.setReceivenum(recvNum);
							couponInfoMapper.updateByPrimaryKey(couponInfo);
						
							SmsSendUtil.sendSmsNotify(userId, couponInfo.getId().toString(), 10, "您有新的优惠券啦!");
						}else if(type == 3){
							HashMap<String, Object> paramMap = new HashMap<String, Object>();
							paramMap.put("getType", type);
							paramMap.put("couponId", couponInfo.getId());
							List<CouponGet> getList = couponGetMapper.selectByCouponIdAndGetType(paramMap);
							if(getList.size() > 0){
								CouponUser couponUser = new CouponUser();
								couponUser.setGetTime(new Date());
								couponUser.setId(UUID.randomUUID().toString().replace("-", ""));
								couponUser.setCouponId(couponInfo.getId());
								couponUser.setCouponNum(1);
								couponUser.setGetType(type);
								couponUser.setUserId(userId);
								couponUser.setParamId(paramId);
								couponUserMapper.insert(couponUser);
								
								CouponGet couponGet = getList.get(0);
								int getNum = couponGet.getGetNum()==null  ? 0 : couponGet.getGetNum();
								
								//查询用户积分
								UserAccount userAccount = userAccountMapper.selectByUserId(couponUser.getUserId());
								int score = userAccount.getScore()==null  ? 0 : userAccount.getScore();
								
								//如果用户积分小于所需积分不允许领取
								if(getNum > score){
									infoMap.put("resultCode", Constants.FAIL);
									infoMap.put("resultDesc", "非常遗憾，您的积分余额不足，领取失败");
									return infoMap;
								}else{
									OrderInfo orderInfo = new OrderInfo();
									orderInfo.setUserId(couponUser.getUserId());
									orderInfo.setOrderStatus(1);
									orderInfo.setAllMoney(getNum);
									orderInfo.setPayMoney(getNum);
									orderInfo.setCouponId(couponUser.getCouponId());
									orderInfo.setOrderTime(new Date());
									orderInfo.setOrderType(2);
									Integer orderId = orderInfoMapper.insertSelective(orderInfo);
									
									String code = "";
									code += orderInfo.getOrderType();
									SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
									code += sdf.format(new Date());
									String codeStr = String.valueOf(orderInfo.getId());
									if(codeStr.length()> 6){
										codeStr = codeStr.substring(codeStr.length()-6);
									}else if(codeStr.length() < 6){
										for (int i = 0; i < 6-codeStr.length(); i++) {
											code += "0";
										}
									}
									code += codeStr;
									orderInfo.setOrderCode(code);
									orderInfoMapper.updateByPrimaryKeySelective(orderInfo);
									
									ScoreHistory his = new ScoreHistory();
									his.setHisId(UUID.randomUUID().toString().replace("-", ""));
									his.setCreateTime(new Date());
									his.setUserId(couponUser.getUserId());
									his.setOpType(0);
									his.setIsFinish(1);
									his.setValNum((long)getNum);
									his.setHisType(3);
									his.setParamId(String.valueOf(couponUser.getCouponId()));
									his.setIsDel(1);
									scoreHistoryMapper.insertSelective(his);
									
									CouponHistory chis = new CouponHistory();
									chis.setHisId(UUID.randomUUID().toString().replace("-", ""));
									chis.setCreateTime(new Date());
									chis.setUserId(couponUser.getUserId());
									chis.setOpType(1);
									chis.setIsFinish(1);
									chis.setValNum(1l);
									chis.setHisType(3);
									chis.setParamId(orderId.toString());
									chis.setIsDel(1);
									chis.setCouponId(couponUser.getCouponId());
									couponHistoryMapper.insertSelective(chis);
									
									userAccount.setScore(userAccount.getScore()-getNum);
									userAccount.setPayType(2);
									userAccount.setUserId(couponUser.getUserId());
									userAccountMapper.updateByPrimaryKey(userAccount);
									
									couponInfo = couponInfoMapper.selectByPrimaryKey(couponInfo.getId());
									Long recvNum = (long)recvCnt+1;
									couponInfo.setReceivenum(recvNum);
									couponInfoMapper.updateByPrimaryKey(couponInfo);
									
									SmsSendUtil.sendSmsNotify(userId, userId, 114, "成功兑换“"+couponInfo.getCouponName()+"”，消耗"+getNum+"积分，您的剩余积分为"+userAccount.getScore()+"，快去赚取更多积分吧~");
									
									SmsSendUtil.sendSmsNotify(userId, couponInfo.getId().toString(), 10, "您有新的优惠券啦!");
									
									infoMap.put("resultCode", Constants.SUCCESS);
									infoMap.put("resultDesc", "恭喜您成功领取了该优惠券");
								}
							}else{
								infoMap.put("resultCode", Constants.FAIL);
								infoMap.put("resultDesc", "非常遗憾，已经被一抢而光啦");
							}
						}
						
					}else{
						infoMap.put("resultCode", Constants.EXCEPTION);
						infoMap.put("resultDesc", "网络请求失败");
						return infoMap;
					}
				}else{
					infoMap.put("resultCode", Constants.FAIL);
					infoMap.put("resultDesc", "非常遗憾，该优惠券已经被抢光啦");
					return infoMap;
				}
			}
			infoMap.put("resultCode", Constants.SUCCESS);
			infoMap.put("resultDesc", Constants.SUCCESS_DESC);
		} catch (Exception e) {
			infoMap.put("resultCode", Constants.EXCEPTION);
			infoMap.put("resultDesc", "网络请求失败");
			logger.error(e.getMessage(),e);
			throw e;
		}
		return infoMap;
	}
}
